package com.lazy.book.strategy;


import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.stp.parameter.SaLoginParameter;
import com.lazy.book.common.entity.BaseUserInfo;
import com.lazy.book.common.entity.LoginUser;
import com.lazy.book.common.pojp.LoginInfo;
import com.lazy.book.common.pojp.LoginVO;
import com.lazy.book.common.utils.LoginUtils;
import com.lazy.book.common.entity.ClientVO;
import com.lazy.book.service.system.IAuthStrategy;
import com.lazy.book.service.system.SysUserService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

/**
 * <p>密码认证策略</p>
 *
 * @author lazy
 * @since 2025-09-04
 */
@Slf4j
@Service("password" + IAuthStrategy.BASE_NAME)
@RequiredArgsConstructor
public class PasswordStrategy implements IAuthStrategy {

  private final SysUserService sysUserService;

  @Override
  public LoginVO login(LoginInfo info, ClientVO client) {
    String clientId = client.getClientId();
    String password = info.getPassword();
    String username = info.getUsername();
    // 设置登录模型
    SaLoginParameter model = createLoginModel(client);
    // 复制用户信息
    LoginUser loginUser = sysUserService.buildLoginUser(username, password);
    Long userId = loginUser.getUserInfo().getId();
    // 设置jwt额外数据
    Map<String, Object> extraData = createExtraData(clientId, userId);
    // 执行登录
    LoginUtils.performLogin(loginUser, model, extraData);
    // 构造返回对象
    return createLoginVO(loginUser.getUserInfo());
  }

  private SaLoginParameter createLoginModel(ClientVO client) {
    SaLoginParameter model = new SaLoginParameter();
    model.setDeviceType(client.getDeviceTypeCd());
    model.setTimeout(client.getTimeout());
    model.setActiveTimeout(client.getActiveTimeout());
    return model;
  }

  private Map<String, Object> createExtraData(String clientId, Long userId) {
    Map<String, Object> extraData = new HashMap<>();
    extraData.put("clientId", clientId);
    extraData.put("userId", userId);
    return extraData;
  }

  private LoginVO createLoginVO(BaseUserInfo userInfo) {
    LoginVO loginVo = new LoginVO();
    loginVo.setAccessToken(StpUtil.getTokenValue());
    loginVo.setExpireIn(StpUtil.getTokenTimeout());
    loginVo.setUserInfo(userInfo);
    return loginVo;
  }
}
